package br.ufpi.controllers;

import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import br.com.caelum.vraptor.Get;
import br.com.caelum.vraptor.Post;
import br.com.caelum.vraptor.Resource;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.Validator;
import br.com.caelum.vraptor.validator.Validations;
import br.ufpi.componets.UserSession;
import br.ufpi.componets.ValidateComponente;
import br.ufpi.model.User;
import br.ufpi.repositories.UserRepository;
import br.ufpi.util.BaseUrl;
import br.ufpi.util.Criptografa;

@Resource
public class LoginController extends BaseController {

	private final UserRepository userRepository;
	private final HttpServletRequest request;

	public LoginController(Result result, Validator validator, UserSession usuarioLogado, ValidateComponente validateComponente,
			UserRepository usuarioRepository, HttpServletRequest request) {
		super(result, validator, usuarioLogado, validateComponente);
		this.userRepository = usuarioRepository;
		this.request = request;
	}

	@Get("/login")
	public void login(String login) {
		result.include("login", login);
	}

	/**
	 * Usada para a pessoa acessar a conta apos o Login.
	 * 
	 * @param email
	 * @param senha
	 */
	@Post("/conta")
	public void conta(final String login, final String senha) {
		validator.checking(new Validations() {

			{
				that(!login.isEmpty(), "campo.login.obrigatorio", "campo.obrigatorio", i18n("login"));
				that(!senha.isEmpty(), "campo.senha.obrigatorio", "campo.obrigatorio", i18n("senha"));
			}
		});
		validator.onErrorRedirectTo(this).login(login);
		String senhaCriptografada = Criptografa.criptografar(senha);
		User user = userRepository.logar(login, senhaCriptografada);
		if (user != null) {
			if (user.getLogin().getIsActive()) {
				usuarioLogado.setUser(user);
				result.redirectTo(this).logado();
			} else {
				result.forwardTo(this).reenviaEmailConfirmacao(user.getLogin().getEmail());
			}

		} else {
			validateComponente.gerarErro("login.senha.invalido", "login.senha.invalido");
			validator.onErrorRedirectTo(this).login(login);
		}
	}

	@Get({ "/usuario" })
	public void logado() {
	}

	@Get({ "usuario/reenviar/email" })
	public void reenviaEmailConfirmacao(String login) {
		result.include("login", login);
	}

	/**
	 * Usuario ao receber o email acessara a pagina passada e esta action valida
	 * a inscrição do usuario. Caso o email de confirmação não for encontrado é
	 * redirecionado para a pagina de Login.
	 * 
	 * @param confirmacaoEmail
	 */
	@Get("/confirmar/{confirmacaoEmail}")
	public void validarInscricao(String confirmacaoEmail) {
		User usuario = userRepository.findConfirmationEmail(confirmacaoEmail);
		if (usuario != null) {
			usuario.getLogin().setIsActive(true);
			usuario.getLogin().setTokenActive(null);
			userRepository.update(usuario);
			result.include(usuario);
		} else {
			result.redirectTo(LoginController.class).login(null);
		}
	}

	/**
	 * Referencia para o usuario desloga da aplicação. Acabando com a seção do
	 * usuario.
	 */
	@Get("/logout")
	public void logout() {
		usuarioLogado.logout();
		result.redirectTo(this).login(null);
	}

	/**
	 * Pagina para o usuario recuperar a senha , onde vai conter apenas o campo
	 * de email do usuario;
	 * 
	 * 
	 * @param login
	 */
	@Get("/usuario/recupera-senha")
	public void recuperaSenha(String login) {
		result.include("login", login);
	}

	/**
	 * Realiza o processo de Reenvio de nova senha para o usuario
	 * 
	 * @param login
	 *            passou o email em que esta cadastrado e o aplicativo envia
	 *            outra senha para o mesmo
	 * @return
	 */
	@Post("usuario/recupera-senha-completa")
	public void recuperaSenhaCompleta(final String login) {
		validator.checking(new Validations() {
			{
				that(!login.isEmpty(), "campo.login.obrigatorio", "campo.obrigatorio", i18n("login"));
			}
		});
		validator.onErrorForwardTo(this).recuperaSenha(login);
		User usuario = userRepository.findLogin(login);
		if (usuario == null) {
			validator.checking(new Validations() {

				{
					that(false, "login.nao.cadastrado", "login.nao.cadastrado");
				}
			});
			validator.onErrorUsePageOf(this).recuperaSenha(login);
		} else {
			String novaSenha = geradorSenha(usuario);
			String senha = Criptografa.criptografar(novaSenha);
			usuario.getLogin().setPassword(senha);
			BaseUrl.getInstance(request);
			// TODO Enviar nova Senha
			userRepository.update(usuario);
			result.include("sucesso", "usuario.senha.redefinida");
			result.redirectTo(this).recuperaSenha(login);
		}
	}

	@Post("usuario/reenviar/email")
	public void reenviaEmailConfirmacaoCompleto(final String login) {
		validator.checking(new Validations() {
			{
				that(!login.isEmpty(), "campo.login.obrigatorio", "campo.obrigatorio", i18n("login"));
			}
		});
		validator.onErrorForwardTo(this).reenviaEmailConfirmacao(login);
		User usuario = userRepository.findLogin(login);
		if (usuario != null) {
			if (usuario.getLogin().getTokenActive() != null) {
				BaseUrl.getInstance(request);
				String urlConfirmacao = BaseUrl.BASEURL + "/confirmar/" + usuario.getLogin().getTokenActive();
				//TODO Enviar Email com a url de confirmação de email
				result.include("email", login);
				result.include("isConfirmado", false);

			} else {
				result.include("email", login);
				result.include("isConfirmado", true);
			}
		} else {
			validator.checking(new Validations() {
				{
					that(false, "login.nao.cadastrado", "login.nao.cadastrado");
				}
			});
			validator.onErrorForwardTo(this).reenviaEmailConfirmacao(login);
		}
	}

	/**
	 * Gera a senha para o Usuario
	 * 
	 * @param usuario
	 *            Usuario ao qual vai ser gerado a senha
	 * @return a senha de tamanho de 8 caracteres
	 */
	private String geradorSenha(User usuario) {
		return Criptografa.criptografar(usuario.getName() + usuario.getLogin().getEmail() + new Date()).substring(0, 8);
	}

}
